package xyz.yuanjilu.aware;

import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import xyz.yuanjilu.service.WorkspaceService;
import xyz.yuanjilu.utils.file.FileUtils;

@Component
public class GroovyFactory implements ApplicationContextAware {  
	Logger logger= LoggerFactory.getLogger(getClass());
	
	@Autowired
	private WorkspaceService workspaceService;
	
    FileFilter filter = new FileFilter() {  
        @Override  
        public boolean accept(File pathname) {  
            return pathname.getName().endsWith(".groovy") ? true : false;  
        }  
    };
	
    private String directory ="groovy";  
      
    public String getDirectory() {  
        return directory;  
    }  
  
    public void setDirectory(String directory) {  
        this.directory = directory;  
    }  
    
    /**
     *在context创建时通过ApplicationContextAware动态扫描目录下面的groovy文件生成bean
     * TODO 
     * @see  <a href="http://blog.csdn.net/qq362228416/article/details/8811136">adadfa</a>
     */
    @Override  
    public void setApplicationContext(ApplicationContext context)  throws BeansException {
    	logger.info("----------------加载GroovyFactory扩展----------------");
    	loadServleSpaceScript(context);
    	loadWorkspaceScript(context);
    }  
      
    
    public void loadWorkspaceScript(ApplicationContext context){
    	
    	  // 只有这个对象才能注册bean到spring容器  
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();  
        
    	File workspaceDirectory = workspaceService.getWorkspaceDirectory();
    	String[] extensions={"groovy"};
    	Collection<File> listFiles = FileUtils.listFiles(workspaceDirectory,extensions,true);
    	
    	 final String refreshCheckDelay = "org.springframework.scripting.support.ScriptFactoryPostProcessor.refreshCheckDelay";  
         final String language = "org.springframework.scripting.support.ScriptFactoryPostProcessor.language";  
         
         for (File file : listFiles) {  
             GenericBeanDefinition bd = new GenericBeanDefinition();  
             bd.setBeanClassName("org.springframework.scripting.groovy.GroovyScriptFactory");  
             // 刷新时间  
             bd.setAttribute(refreshCheckDelay, 500);  
             // 语言脚本  
             bd.setAttribute(language, "groovy");  
             // 文件目录  
             bd.getConstructorArgumentValues().addIndexedArgumentValue(0, "file:"+file.getPath());  
//             bd.getConstructorArgumentValues().addIndexedArgumentValue(0, "classpath:groovy/FooImpl.groovy");  
             // 注册到spring容器  
             beanFactory.registerBeanDefinition(file.getName().replace(".groovy", ""), bd);  
         }  
    	
    }
    public void loadServleSpaceScript(ApplicationContext context){
        // 只有这个对象才能注册bean到spring容器  
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();  
          
        // 因为spring会自动将xml解析成BeanDefinition对象然后进行实例化，这里我们没有用xml，所以自己定义BeanDefinition  
        // 这些信息跟spring配置文件的方式差不多，只不过有些东西lang:groovy标签帮我们完成了  
        final String refreshCheckDelay = "org.springframework.scripting.support.ScriptFactoryPostProcessor.refreshCheckDelay";  
        final String language = "org.springframework.scripting.support.ScriptFactoryPostProcessor.language";  
       
       
        String realDirectory = Thread.currentThread().getContextClassLoader().getResource(directory).getFile();  
        URL resource = Thread.currentThread().getContextClassLoader().getResource("/");//servlet容器环境下
        if (resource==null) {
        	 resource = Thread.currentThread().getContextClassLoader().getResource(".");//jar环境下，或是Junit单元测试环境下
		}
		File root = new File(resource.getFile());  
		
        File[] files = new File(realDirectory).listFiles(filter); 
        
        for (File file : files) {  
            GenericBeanDefinition bd = new GenericBeanDefinition();  
            bd.setBeanClassName("org.springframework.scripting.groovy.GroovyScriptFactory");  
            // 刷新时间  
            bd.setAttribute(refreshCheckDelay, 500);  
            // 语言脚本  
            bd.setAttribute(language, "groovy");  
            // 文件目录  
            bd.getConstructorArgumentValues().addIndexedArgumentValue(0, "classpath:"+file.getPath().replace(root.getPath(), ""));  
//            bd.getConstructorArgumentValues().addIndexedArgumentValue(0, "classpath:groovy/FooImpl.groovy");  
            // 注册到spring容器  
            beanFactory.registerBeanDefinition(file.getName().replace(".groovy", ""), bd);  
        }  
          
    }
}  
